﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace RCSnake
	{
	/// <summary>
	/// 
	/// </summary>
	public partial class FormConfig : Form
		{

		/*---------------------------------------------*\
		|*                 Attributs                   *|
		\*---------------------------------------------*/
		public enum m_enumDirection { Up, Down, Left, Right };
		public String m_backupUp;
		public String m_backupDown;
		public String m_backupLeft;
		public String m_backupRight;
		/*---------------------------------------------*\
		|*                Constructeur                 *|
		\*---------------------------------------------*/
		/// <summary>
		/// 
		/// </summary>
		public FormConfig()
			{
			InitializeComponent();
			this.fillAllComboBox();

			if(!File.Exists(Parameters.DEFAULT_CONFIG_FILENAME))
				{
				createXML();
				}
			String up = "";
			String down = "";
			String left = "";
			String right = "";
			try
				{
				up = getValueButtonXml(m_enumDirection.Up);
				down = getValueButtonXml(m_enumDirection.Down);
				left = getValueButtonXml(m_enumDirection.Left);
				right = getValueButtonXml(m_enumDirection.Right);
				}
			catch(Exception f)
				{
				MessageBox.Show(f.ToString(), "Getting keys in config file error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}

			selectInComboBox(up, ref m_cmbUp, Keys.Up.ToString());
			selectInComboBox(down, ref m_cmbDown, Keys.Down.ToString());
			selectInComboBox(left, ref m_cmbLeft, Keys.Left.ToString());
			selectInComboBox(right, ref m_cmbRight, Keys.Right.ToString());

			saveSelectedItems();
			}


		/*---------------------------------------------*\
		|*               Methodes public               *|
		\*---------------------------------------------*/
		public void saveKeyboardConfig()
			{
			try
				{
				XDocument document = XDocument.Load(Parameters.DEFAULT_CONFIG_FILENAME);
				XElement root = document.Root;

				root.Elements("button").Where(e => e.Attribute("name").Value.Equals(m_enumDirection.Up.ToString())).Single().SetValue(m_backupUp);
				root.Elements("button").Where(e => e.Attribute("name").Value.Equals(m_enumDirection.Down.ToString())).Single().SetValue(m_backupDown);
				root.Elements("button").Where(e => e.Attribute("name").Value.Equals(m_enumDirection.Left.ToString())).Single().SetValue(m_backupLeft);
				root.Elements("button").Where(e => e.Attribute("name").Value.Equals(m_enumDirection.Right.ToString())).Single().SetValue(m_backupRight);

				document.Save(Parameters.DEFAULT_CONFIG_FILENAME);
				}
			catch(Exception e)
				{
				MessageBox.Show(e.ToString(), "Saving keys config error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

		/*---------------------*\
		|*      get / set      *|
		\*---------------------*/
		/// <summary>
		/// 
		/// </summary>
		public String up
			{
			get { return m_backupUp; }
			}

		/// <summary>
		/// 
		/// </summary>
		public String down
			{
			get { return m_backupDown; }
			}

		/// <summary>
		/// 
		/// </summary>
		public String left
			{
			get { return m_backupLeft; }
			}

		/// <summary>
		/// 
		/// </summary>
		public String right
			{
			get { return m_backupRight; }
			}

		/*---------------------------------------------*\
		|*              Methodes private               *|
		\*---------------------------------------------*/
		private static void createXML()
			{
			try
				{
				XDocument document = new XDocument(
						new XDeclaration("1.0", "utf-8", "yes"),
						new XElement("keyboard",
						new XElement("button", new XAttribute("name", "Up"), m_enumDirection.Up.ToString()),
						new XElement("button", new XAttribute("name", "Down"), m_enumDirection.Down.ToString()),
						new XElement("button", new XAttribute("name", "Left"), m_enumDirection.Left.ToString()),
						new XElement("button", new XAttribute("name", "Right"), m_enumDirection.Right.ToString())));
				document.Save(Parameters.DEFAULT_CONFIG_FILENAME);
				}
			catch(Exception e)
				{
				MessageBox.Show(e.ToString(), "Creating keys config file error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="dir">La direction (haut, bas, gauche, droite)</param>
		/// <param name="cmb">La comboBox dans laquelle on va sélectionner la touche</param>
		/// <param name="key">La valeur par défaut si la touche ne se trouve pas dans le fichier XML ou si la touche est erronée</param>
		private void selectInComboBox(String dir, ref ComboBox cmb, String key)
			{
			if(dir.Length == 0)
				{
				dir = key;
				}

			if(cmb.Items.Contains(dir))
				{
				cmb.SelectedItem = dir;
				}
			else
				{
				cmb.SelectedItem = key;
				}
			}

		/// <summary>
		/// Permet de récupérer les touches de direction dans un fichier XML
		/// </summary>
		/// <param name="direction"></param>
		/// <returns></returns>
		private String getValueButtonXml(m_enumDirection direction)
			{
			String str = "";
			try
				{
				var set = from boutton in XDocument.Load(Parameters.DEFAULT_CONFIG_FILENAME).Descendants("button")
						  where boutton.Attribute("name").Value.Equals(direction.ToString())
						  select boutton.Value;

				foreach(var s in set)
					{
					str += s.ToString();
					}
				}
			catch(Exception)
				{
				throw;
				}
			return str;
			}

		/// <summary>
		/// Cette méthode permet de remplir une combobox avec toutes les lettres de l'alphabet (minuscules et majuscules), ainsi qu'avec les flèches de directions.
		/// </summary>
		/// <param name="cmb">La comboBox à remplir</param>
		private void fillComboBox(ref ComboBox cmb)
			{
			//Insertion des touches de direction
			cmb.Items.Add(Keys.Up.ToString());
			cmb.Items.Add(Keys.Down.ToString());
			cmb.Items.Add(Keys.Left.ToString());
			cmb.Items.Add(Keys.Right.ToString());

			//Insertion des lettres majuscules
			for(int i = 65 ; i <= 90 ; ++i)
				{
				cmb.Items.Add(((char)i).ToString());
				}
			}

		private void fillAllComboBox()
			{
			this.fillComboBox(ref m_cmbUp);
			this.fillComboBox(ref m_cmbDown);
			this.fillComboBox(ref m_cmbLeft);
			this.fillComboBox(ref m_cmbRight);
			}

		private void backupSelectedItems()
			{
			m_cmbUp.SelectedItem = m_backupUp;
			m_cmbDown.SelectedItem = m_backupDown;
			m_cmbLeft.SelectedItem = m_backupLeft;
			m_cmbRight.SelectedItem = m_backupRight;
			}

		private void saveSelectedItems()
			{
			m_backupUp = m_cmbUp.SelectedItem.ToString();
			m_backupDown = m_cmbDown.SelectedItem.ToString();
			m_backupLeft = m_cmbLeft.SelectedItem.ToString();
			m_backupRight = m_cmbRight.SelectedItem.ToString();
			}

		/*---------------------*\
		|*        slot         *|
		\*---------------------*/
		private void m_btnCancel_Click(object sender, EventArgs e)
			{
			this.backupSelectedItems();
			this.Close();
			}

		private void m_btnOk_Click(object sender, EventArgs e)
			{
			this.saveSelectedItems();
			this.Close();
			}
		}
	}
